package com.swf.seed.algorithms.tree;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

/**
 * ClassName: Node <br/>
 * Function: 树的节点. <br/>
 * Reason: 一颗多叉树. <br/>
 * date: 2015-1-23 上午10:29:51 <br/>
 *
 * @author shenwf10476
 * @version 
 * @since JDK 1.6
 */
public class Node implements Cloneable {
	private Character key;
	private Node parent;
	private Set<Node> childrens;
	private int height;
	private boolean end;

	public Node() {
		childrens = new HashSet<Node>();
	}

	public void setKey(char key) {
		this.key = key;
	}

	public Character getKey() {
		return key;
	}

	public void setParent(Node parent) {
		this.parent = parent;
	}

	public Node getParent() {
		return parent;
	}

	public Set<Node> getChildrens() {
		return childrens;
	}

	public Node[] getChildArray() {
		return childrens.toArray(new Node[childrens.size()]);
	}

	public boolean isEnd() {
		return end;
	}

	public void setEnd(boolean end) {
		this.end = end;
	}

	public int getHeight() {
		return height;
	}

	public void setHeight(int height) {
		this.height = height;
	}

	public void addChild(Node child) {
		if (child.getKey() != null) {
			childrens.add(child);
		}
	}

	public void removeChild(Node child) {
		Node inner = getChild(child.getKey());
		if (inner != null) {
			childrens.remove(inner);
		}
	}

	public boolean hasChild() {
		return !childrens.isEmpty();
	}

	public boolean equalsKey(Node node) {
		if (node == null) {
			return false;
		}
		return this.getKey().equals(node.getKey());
	}

	public static void main(String[] args) {
		Node node = new Node();
		node.setKey('啊');
		Node node1 = new Node();
		node1.setKey('有');
		Node node2 = new Node();
		node2.setKey('我');
		Node node3 = new Node();
		node3.setKey('啊');
		node2.addChild(node3);
		node.addChild(node2);
		node.addChild(node1);
		System.out.println(node);
	}

	public void merge(Node node) {
		if (this.getKey().equals(node.getKey())) {
			if (node.hasChild()) {
				Node child = node.getChild(0);
				if (containsChild(child)) {
					Node child1 = getChild(child.getKey());
					child1.merge(child);
				} else {
					addChild(child);
				}
			} else {
				this.setEnd(true);
			}
		}
	}

	
	public Node getChild(int index) {
		return childrens.toArray(new Node[childrens.size()])[index];
	}

	public Node getChild(Character key) {
		Iterator<Node> iterator = childrens.iterator();
		while (iterator.hasNext()) {
			Node value = iterator.next();
			if (value.getKey().equals(key)) {
				return value;
			}
		}
		return null;
	}

	public boolean containsChild(Node node) {
		Iterator<Node> iterator = childrens.iterator();
		while (iterator.hasNext()) {
			if (iterator.next().equalsKey(node)) {
				return true;
			}
		}
		return false;
	}

	public boolean containsChild(char key) {
		Iterator<Node> iterator = childrens.iterator();
		while (iterator.hasNext()) {
			if (iterator.next().getKey().equals(key)) {
				return true;
			}
		}
		return false;
	}

	protected void setChildrens(Set<Node> childrens) {
		this.childrens = childrens;
	}

	@Override
	public Node clone() {
		Node node = new Node();
		node.setKey(this.getKey());
		node.setParent(this.getParent());
		node.setEnd(this.isEnd());
		node.setChildrens(this.getChildrens());
		return node;
	}
	
	@Override
	public String toString() {
		StringBuilder sb = new StringBuilder("");
		sb.append("").append(key);
		if (isEnd()) {
			sb.append("$");
		}
		if (!childrens.isEmpty()) {
			sb.append("(");
			Node[] childs = getChildArray();
			for (int i = 0; i < childs.length; i++) {
				if (i != 0) {
					sb.append(",");
				}
				sb.append(childs[i]);
			}
			sb.append(")");
		}
		return sb.toString();
	}

}
